package edu.isistan.matching;

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;

import edu.isistan.vsm.IVectorSpace;
import edu.isistan.vsm.Representation;
import edu.isistan.vsm.reducer.ISpaceReducer;

/**
 * Reorganiza el espacio de acuerdo a la estructura del query
 * 
 * @author Mariano Fischer
 * 
 */
public class StructuralReducer implements ISpaceReducer {
	
	static Logger logger = Logger.getLogger(StructuralReducer.class);
	IMatchingAlgorithm serviceSimilarity = null;

	public StructuralReducer(IMatchingAlgorithm similarity) {
		this.serviceSimilarity = similarity;
	}

	public Iterator<Representation> reduce(IVectorSpace space, Representation query) {
		try {
			WSDLRepresentation wsdlQuery = (WSDLRepresentation) query;
			List representations = new LinkedList();
			List retorno = new LinkedList();
			Iterator<Representation> spaceServices = space.vectors();
			while (spaceServices.hasNext()) {
				WSDLRepresentation representation = (WSDLRepresentation) spaceServices.next();
				MatchProcessor procesor = new MatchProcessor(this.serviceSimilarity);
				double score = procesor.scoreMatching(wsdlQuery.getWsdlURL().getPath(), representation.getWsdlURL().getPath());
				WSDLScoreService wrapperService = new WSDLScoreService(representation);
				wrapperService.setScore(score);
				representations.add(wrapperService);
			}
			Collections.sort(representations,new WSDLScoreServiceCompartor());
			Iterator<WSDLScoreService> it = representations.iterator();
			while (it.hasNext()) {
				retorno.add(it.next().getRepresentation());
			}
			return retorno.iterator();
		} catch (Exception e) {
			logger.error("Error en la reduccion structural: " + e.getMessage());
			// Se retorna el vector sin realizar la reduccion
			return space.vectors();
		}
	}

	class WSDLScoreService {
		private WSDLRepresentation representation;

		public WSDLScoreService(WSDLRepresentation rep) {
			this.representation = rep;
		}

		double score;

		public double getScore() {
			return score;
		}

		public void setScore(double score) {
			this.score = score;
		}

		public WSDLRepresentation getRepresentation() {
			return representation;
		}
	}

	class WSDLScoreServiceCompartor implements Comparator<WSDLScoreService> {

		public int compare(WSDLScoreService o1, WSDLScoreService o2) {
			return new Double(o2.getScore()).compareTo(new Double(o1.getScore()));
		}
	}
}
